package com.welink.cmp.topotree.command;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.welink.cmp.convertor.GenericConvertor;
import com.welink.cmp.dao.tree.DeviceTopologyDaoService;
import com.welink.cmp.dao.tree.dataobejct.DeviceTopologyTreeDO;
import com.welink.cmp.domain.metadata.Host;
import com.welink.cmp.domain.metadata.Switch;
import com.welink.cmp.domain.topotree.DeviceNetTopoDomain;
import com.welink.cmp.domain.topotree.DeviceTopologyTree;
import com.welink.cmp.domain.topotree.IDeviceTopoGateway;
import com.welink.cmp.dto.topotree.BuildNetTopologyAddCmd;
import com.welink.cmp.dto.topotree.ModifyNetTopologyUptCmd;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yanwei li create  2024-06-03 21:13
 */
@Component
public class NetTopologyCmdExe {

    @Autowired
    private DeviceTopologyDaoService deviceTopologyDaoService;

    @Autowired
    private IDeviceTopoGateway deviceTopoGateway;

    /**
     * 保存NetTopology信息
     *
     * @param createCmd 创建NetTopology的命令对象
     * @return 新增NetTopology的ID
     */
    public Long save(BuildNetTopologyAddCmd createCmd) {
        DeviceTopologyTreeDO netTopologyDO = new DeviceTopologyTreeDO();
        BeanUtils.copyProperties(createCmd,netTopologyDO);
        if (createCmd.isNeedsOperator()){
            netTopologyDO.setCreateBy(createCmd.getOperator());
        }
        deviceTopologyDaoService.save(netTopologyDO);
        return netTopologyDO.getId();
    }

    /**
     * 更新NetTopology信息
     *
     * @param updateCmd 更新NetTopology的命令对象
     * @return 更新是否成功
     */
    public Boolean update(ModifyNetTopologyUptCmd updateCmd) {
        DeviceTopologyTreeDO netTopologyDO = new DeviceTopologyTreeDO();
        BeanUtils.copyProperties(updateCmd, netTopologyDO);
        if (updateCmd.isNeedsOperator()){
            netTopologyDO.setUpdateBy(updateCmd.getOperator());
        }
        return deviceTopologyDaoService.updateById(netTopologyDO);
    }

    public DeviceTopologyTreeDO getById(Long id){
        final DeviceTopologyTreeDO byId = deviceTopologyDaoService.getById(id);
        return byId;
    }


    /**
     * 根据 节点名称 查询NetTopology信息
     *
     * @param name NetTopology ID
     * @return NetTopology业务对象
     */
    public DeviceNetTopoDomain querySwitchNodesByName(String name) {
        DeviceNetTopoDomain domain = new DeviceNetTopoDomain();
        final List<Switch> switchNodes = deviceTopoGateway.getSwitchNodes(name);
        domain.setLocalDevice(name);
        domain.setSwitchNodes(switchNodes);
        return domain;
    }

    /**
     * 根据 节点名称 查询NetTopology信息
     *
     * @param name NetTopology ID
     * @return NetTopology业务对象
     */
    public DeviceNetTopoDomain queryHostsNodesByName(String name) {
        DeviceNetTopoDomain domain = new DeviceNetTopoDomain();
        final List<Host> hostNodes = deviceTopoGateway.getHostNodes(name);
        domain.setLocalDevice(name);
        domain.setHostsNodes(hostNodes);
        return domain;
    }

    public List<Long>  expansionNodes(Long id){
        final DeviceTopologyTreeDO localNode = deviceTopologyDaoService.getById(id);
        if (localNode!=null && localNode.getLocalDevice() !=null) {
            LambdaQueryWrapper<DeviceTopologyTreeDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DeviceTopologyTreeDO::getNeighborDevice,localNode.getLocalDevice());
            final List<DeviceTopologyTreeDO> list = deviceTopologyDaoService.list(queryWrapper);
            if (list == null) {
                return list.stream().map(DeviceTopologyTreeDO::getId).collect(Collectors.toList());
            }
        }
        return null;
    }

    @Transactional
    public Boolean saveOrUpdateBatch(List<DeviceTopologyTree> deviceTopologyTreeList){
        final List<DeviceTopologyTreeDO> doList = GenericConvertor.toDOList(deviceTopologyTreeList, DeviceTopologyTreeDO.class);
        final List<String> nameList = deviceTopologyTreeList.stream().map(DeviceTopologyTree::getNeighborDevice).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(nameList)){
            LambdaUpdateWrapper<DeviceTopologyTreeDO> deleteWrapper = Wrappers.lambdaUpdate(DeviceTopologyTreeDO.class);
            deleteWrapper.set(DeviceTopologyTreeDO::getIsDel,1);
            deleteWrapper.in(DeviceTopologyTreeDO::getNeighborDevice,nameList);
            final boolean update = deviceTopologyDaoService.update(deleteWrapper);
        }
        final boolean b = deviceTopologyDaoService.saveOrUpdateBatch(doList);
        return b;
    }

}
